﻿using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;

namespace Jim.K3Cloud
{
    public static class EnDecode
    {
        public static string Encode(object data)
        {
            string s1 = "K3CloudK";
            string s2 = "K3CloudK";
            try
            {
                byte[] bytes1 = Encoding.ASCII.GetBytes(s1);
                byte[] bytes2 = Encoding.ASCII.GetBytes(s2);
                byte[] inArray = (byte[])null;
                int length = 0;
                using (var cryptoServiceProvider = DES.Create())
                {
                    int keySize = cryptoServiceProvider.KeySize;
                    using (MemoryStream memoryStream = new MemoryStream())
                    {
                        using (CryptoStream cryptoStream = new CryptoStream((Stream)memoryStream, cryptoServiceProvider.CreateEncryptor(bytes1, bytes2), CryptoStreamMode.Write))
                        {
                            using (StreamWriter streamWriter = new StreamWriter((Stream)cryptoStream))
                            {
                                streamWriter.Write(data);
                                streamWriter.Flush();
                                cryptoStream.FlushFinalBlock();
                                streamWriter.Flush();
                                inArray = memoryStream.GetBuffer();
                                length = (int)memoryStream.Length;
                            }
                        }
                    }
                }
                return System.Convert.ToBase64String(inArray, 0, length);
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        public static string HmacSHA256(string message, string secret, Encoding encoding, bool isHex = false)
        {
            secret = secret ?? "";
            byte[] bytes1 = encoding.GetBytes(secret);
            byte[] bytes2 = encoding.GetBytes(message);
            using (HMACSHA256 hmacshA256 = new HMACSHA256(bytes1))
            {
                byte[] hash = hmacshA256.ComputeHash(bytes2);
                if (!isHex)
                    return System.Convert.ToBase64String(hash);
                string lower = EnDecode.ByteToHexStr(hash).ToLower();
                return System.Convert.ToBase64String(encoding.GetBytes(lower));
            }
        }

        public static string ByteToHexStr(byte[] bytes)
        {
            string hexStr = "";
            if (bytes != null)
            {
                for (int index = 0; index < bytes.Length; ++index)
                    hexStr += bytes[index].ToString("X2");
            }
            return hexStr;
        }

        internal static string EncryptAppSecret(string appSecret) => Regex.IsMatch(appSecret, "^([0-9a-zA-Z]{32})$") ? System.Convert.ToBase64String(EnDecode.XOREncode(System.Convert.FromBase64String(appSecret))) : EnDecode.ROT13Encode(appSecret);

        internal static string DecryptAppSecret(string appSecret) => appSecret.Length == 32 ? System.Convert.ToBase64String(EnDecode.XOREncode(System.Convert.FromBase64String(appSecret))) : EnDecode.ROT13Encode(appSecret);

        private static byte[] XOREncode(byte[] input)
        {
            string str = "";
            string s = !string.IsNullOrWhiteSpace(str) ? (str.Length < 24 ? str.PadRight(24, '8') : str) : "0054f397c6234378b09ca7d3e5debce7";
            byte[] numArray = new byte[input.Length];
            byte[] bytes = Encoding.UTF8.GetBytes(s);
            for (int index = 0; index < input.Length; ++index)
                numArray[index] = BitConverter.GetBytes((int)input[index] ^ (int)bytes[index])[0];
            return numArray;
        }

        private static string ROT13Encode(string InputText)
        {
            string str = "";
            for (int startIndex = 0; startIndex < InputText.Length; ++startIndex)
            {
                int num = (int)System.Convert.ToChar(InputText.Substring(startIndex, 1));
                if (num >= 97 && num <= 109)
                    num += 13;
                else if (num >= 110 && num <= 122)
                    num -= 13;
                else if (num >= 65 && num <= 77)
                    num += 13;
                else if (num >= 78 && num <= 90)
                    num -= 13;
                str += ((char)num).ToString();
            }
            return str;
        }

        public static string UrlEncodeWithUpperCode(string str, Encoding encoding)
        {
            StringBuilder stringBuilder = new StringBuilder();
            foreach (char ch in str)
            {
                if (HttpUtility.UrlEncode(ch.ToString()).Length > 1)
                    stringBuilder.Append(HttpUtility.UrlEncode(ch.ToString(), encoding).ToUpper());
                else
                    stringBuilder.Append(ch);
            }
            return stringBuilder.ToString();
        }
    }
}
